package com.action.app;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.bean.ResponseBean;
import com.pojo.*;
import com.service.*;
import com.util.JwtUtil;
import com.util.MD5Util;
import com.util.PasswordUtil;
import com.util.StringUtil;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.mail.MailSendException;
import org.springframework.mail.SimpleMailMessage;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.web.bind.annotation.*;

import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;

@RequestMapping("app/v1")
@RestController
public class AppUserAction {

    @Autowired
    private AppAdminService adminService ;

    @Value("${mail.fromMail.sender}")
    private String sender;// 发送者

    @Autowired
    private JavaMailSender javaMailSender;

    @Autowired
    private RedisTemplate redisTemplate;
    @Autowired
    private StringRedisTemplate stringRedisTemplate;
    @Autowired
    private RedissonClient redissonClient;
    @Autowired
    private ContentsService contentsService;
    @Autowired
    private DictionaryService dictionaryService;
    @Autowired
    private ZhujiService zhujiService;
    @Autowired
    private AreaService areaService;

//    private Map<String, Object> resultMap = new HashMap<>();

    /**
     * 发送邮箱获取验证码
     * @param email    邮箱地址
     * @return
     */
    @RequestMapping("/sendEmail")
    public ResponseBean sendEmail(String email) {
        SimpleMailMessage message = new SimpleMailMessage();
        String code = PasswordUtil.VerifyCode(6);    //随机数生成6位验证码
        message.setFrom(sender);
        message.setTo(email);
        message.setSubject("VPN");// 标题
        message.setText("【VPN】你的验证码为："+code+"，有效时间为5分钟(若不是本人操作，可忽略该条邮件)");// 内容
        try {
            javaMailSender.send(message);
            saveCode(email,code);
            return new ResponseBean(1,1,"文本邮件发送成功","");
        }catch (MailSendException e){
            return new ResponseBean(0,1,"目标邮箱不存在","");
        } catch (Exception e) {
            return new ResponseBean(0,1,"文本邮件发送异常","");
        }
    }

    //保存验证码和时间
    private void saveCode(String email,String code){
        String hash =  MD5Util.code(code);//生成MD5值
        redisTemplate.boundValueOps(email).set(hash);
        redisTemplate.expire(email, 5, TimeUnit.MINUTES);
//        redisTemplate.boundValueOps("tamp").set(currentTime);
//        resultMap.put("hash", hash);
//        resultMap.put("tamp", currentTime);
    }
    /**
     * 新增app用户           注册app用户
     * @param appAdmin     app用户对象
     * @param identify     获取的邮箱验证码
     * @return
     */
    @RequestMapping("/regist")
    public ResponseBean addUser(@RequestBody AppAdmin appAdmin, @RequestParam String identify){

        if (StringUtil.isNull(appAdmin.getMail())) {
            return new ResponseBean(1,1,"邮箱不能为空","");
        }
        if(StringUtil.isNull(appAdmin.getUsername()) || StringUtil.isNull(appAdmin.getPassword())){
            return new ResponseBean(1,1,"用户名或密码不能为空","");
        }
        AppAdmin appAdmin1 = adminService.getOne(new QueryWrapper<AppAdmin>().eq("mail",appAdmin.getMail()));
        if(appAdmin1 != null){
            return new ResponseBean(1,1,"邮箱已被注册","");
        }
        Object email = redisTemplate.boundValueOps(appAdmin.getMail()).get();
        if(email != null){
            if (StringUtil.isNull(email.toString())){
                return new ResponseBean(1,1,"请先验证邮箱","");
            }
        }else {
            return new ResponseBean(1,1,"请先验证邮箱","");
        }
        RLock rLock = redissonClient.getLock(appAdmin.getMail());
        try {
            boolean  f = rLock.tryLock(0,2000, TimeUnit.MILLISECONDS);
            if(f){
                //判断验证码是否正确
                String requestHash = redisTemplate.boundValueOps(appAdmin.getMail()).get().toString();

                String tamp = redisTemplate.boundValueOps(appAdmin.getMail()).get().toString();
                if (StringUtil.isNotNull(tamp)) {
                    String hash =  MD5Util.code(identify);//生成MD5值
                    if (hash.equalsIgnoreCase(requestHash)){
                        //校验成功
                        appAdmin.setPassword(PasswordUtil.jiami(appAdmin.getPassword()));
                        appAdmin.setCreate_time(new Date());
                        appAdmin.setStatus(1);
                        appAdmin.setJiasu_time(0);
                        appAdmin.setShenyu_time(0);
                        Dictionary dictionary = dictionaryService.getOne(new QueryWrapper<Dictionary>().eq("code","zhuce_shijian").eq("type","zhuce_shijian").last("limit 1"));
                        if(dictionary != null && StringUtil.isNotNull(dictionary.getValue())){
                            appAdmin.setShenyu_time(Integer.valueOf(dictionary.getValue()));   //注册赠送时间
                        }
                        if(adminService.save(appAdmin)){
                            return new ResponseBean(200,1,"操作成功","");
                        }
                    }else {
                        //验证码不正确，校验失败
                        return new ResponseBean(1,1,"验证码输入不正确","");
                    }
                } else {
                    // 超时
                    return new ResponseBean(1,1,"验证码已过期","");
                }
            }
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            if(rLock.isLocked()) {
                if(rLock.isHeldByCurrentThread()) {
                    rLock.unlock();
                }
            }
        }
        return new ResponseBean(1,1,"操作失败","");
    }

    /**
     * 登录
     * @param appAdmin   app用户对象
     * @return
     */
    @RequestMapping("login")
    public ResponseBean login(@RequestBody AppAdmin appAdmin){
        if(StringUtil.isNull(appAdmin.getUsername())) {
            return ResponseBean.error("请输入邮箱地址") ;
        }
        if(StringUtil.isNull(appAdmin.getPassword())) {
            return ResponseBean.error("请输入密码") ;
        }
        String pwd = PasswordUtil.jiami(appAdmin.getPassword());
        QueryWrapper<AppAdmin> query = new QueryWrapper() ;
        query.eq("mail",appAdmin.getUsername());
        query.eq("password" , pwd) ;
        query.last("limit 1") ;
        AppAdmin business = adminService.getOne(query);
        if (null == business) {
            return new ResponseBean(500,1,"邮箱或密码错误！",null);
        }
        if ( business.getStatus() != 1) {
            return new ResponseBean(500,1,"该用户已被禁用！",null);
        }
        String token = JwtUtil.generToken(business.getId(),null,null);
        if (token != null){
            Map map = new HashMap<>();
            map.put("bh", business.getUsername());
            map.put("token", token);
            return new ResponseBean(200,1,"认证成功！",map);
        }
        return new ResponseBean(500,1,"认证失败！",null);
    }

    /**
     * 用户修改密码
     * @return
     */
    @RequestMapping("update_pwd")
    public ResponseBean updatePwd(String opwd , String npwd , @RequestHeader String token){
        if(StringUtil.isNull(opwd)) {
            return ResponseBean.error("旧密码不能为空") ;
        }
        if(StringUtil.isNull(npwd)) {
            return ResponseBean.error("新密码不能为空") ;
        }
        String res = adminService.appUpdatePassword(opwd , npwd , token) ;
        return res == null ? ResponseBean.OK : ResponseBean.error(res) ;
    }

    /**
     * 请求用户状态
     * @param token  用户请求令牌
     * @return
     */
    @RequestMapping("user_status")
    public ResponseBean userStatus(@RequestHeader(value = "token",required = false) String token){
        if(StringUtil.isNull(token)){
            return ResponseBean.error("请先登录");
        }
        try{
            JwtUtil.verifyToken(token) ;
        }catch(Exception e) {
            return ResponseBean.error("请先登录") ;
        }
        String uid = JwtUtil.getUsername(token) ;
        AppAdmin appAdmin = adminService.getById(uid) ;
        if(appAdmin != null){
            if(appAdmin.getStatus() == 0) {
                return new ResponseBean(1,0,"用户已禁用","");
            }else{
                return ResponseBean.OK ;
            }
        }
        return ResponseBean.error("请先登录");
    }

    /**
     * 时长计算
     * @param type   0为第一次启动，1为正常启动
     * @param shebei_id  设备id
     * @param zhuji_id  主机id
     * @param token  用户请求令牌
     * @return   总计使用时长      剩余时长
     */
    @RequestMapping("shichang")
    public ResponseBean shichang(int type,String shebei_id,String zhuji_id,@RequestHeader(value = "token" , required = false) String token){
        String uid = JwtUtil.getUsername(token);
        AppAdmin appAdmin = adminService.getById(uid);
        Long time = new Date().getTime();
        if(StringUtil.isNull(shebei_id) || StringUtil.isNull(zhuji_id)){
            return new ResponseBean(500,1,"设备或主机参数不正确！",null);
        }
        if(appAdmin != null){
            if(appAdmin.getStatus() == 0) {
                return new ResponseBean(1,1,"用户已禁用","");
            }
            if(appAdmin.getShenyu_time() == null || appAdmin.getShenyu_time() <= 0){
                return new ResponseBean(501,1,"您的剩余时长已使用完，请先充值！",null);
            }
            if(type == 1){
                Integer Minutes = -1;
                if(stringRedisTemplate.opsForHash().get("time_"+shebei_id,"start_time_"+shebei_id) != null && stringRedisTemplate.opsForHash().get("time_"+shebei_id,"sum_time_"+shebei_id)!= null){
                    Long a = time - Long.valueOf(stringRedisTemplate.opsForHash().get("time_"+shebei_id,"start_time_"+shebei_id).toString());   //获得总共消费时间
                    Minutes =(int) (a / (1000 * 60 )) - Integer.valueOf(stringRedisTemplate.opsForHash().get("time_"+shebei_id,"sum_time_"+shebei_id).toString()); //总共消费时间 - redis中的总消费时间
//                    System.out.println(Minutes);
                }
               if(Minutes < 0){
                   return new ResponseBean(500,1,"非法请求！",null);
               }
               if(appAdmin.getShenyu_time()-Minutes < 0){
                   return new ResponseBean(500,1,"剩余时间不能小于零！",null);
               }
               appAdmin.setJiasu_time(appAdmin.getJiasu_time()+Minutes);
               appAdmin.setShenyu_time(appAdmin.getShenyu_time()-Minutes);
               adminService.updateById(appAdmin);
                //保存前端时间戳
                stringRedisTemplate.opsForHash().put("time_"+shebei_id,"start_time_"+shebei_id,stringRedisTemplate.opsForHash().get("time_"+shebei_id,"start_time_"+shebei_id));
                stringRedisTemplate.opsForHash().put("time_"+shebei_id,"gengxin_time",String.valueOf(time));
                stringRedisTemplate.opsForHash().put("time_"+shebei_id,"sum_time_"+shebei_id,String.valueOf((time - Long.valueOf(stringRedisTemplate.opsForHash().get("time_"+shebei_id,"start_time_"+shebei_id).toString()))/ (1000 * 60 )));
                stringRedisTemplate.opsForHash().put("time_"+shebei_id,"zhuji_id",zhuji_id);
                return new ResponseBean(200,1,"总加速时长和剩余时长",appAdmin);
            }else {
                //把第一次启动的时间戳信息保存到redis中
                stringRedisTemplate.opsForHash().put("time_"+shebei_id,"start_time_"+shebei_id,String.valueOf(time));
                stringRedisTemplate.opsForHash().put("time_"+shebei_id,"gengxin_time",String.valueOf(time));
                stringRedisTemplate.opsForHash().put("time_"+shebei_id,"sum_time_"+shebei_id,String.valueOf(0));
                stringRedisTemplate.opsForHash().put("time_"+shebei_id,"zhuji_id",zhuji_id);
                return new ResponseBean(200,1,"启动返回",appAdmin);
            }

        }else {
            return new ResponseBean(500,1,"请先登录！",null);
        }
    }

    /**
     * app主页接口
     * @param token  用户请求令牌
     * @return  轮播  页面跳转  appAdmin
     */
    @RequestMapping("zhuye")
    public ResponseBean zhuye(@RequestHeader(value = "token" , required = false) String token){

        AppAdmin appAdmin = null;
        if(StringUtil.isNotNull(token)){
            String uid = JwtUtil.getUsername(token);
            appAdmin = adminService.getById(uid);
        }
        Map<String, Object> map = new HashMap();
        Contents contents = contentsService.getOne(new QueryWrapper<Contents>().eq("status",1).last("limit 1"));
        Dictionary paomadeng = dictionaryService.getOne(new QueryWrapper<Dictionary>().eq("code","paomadeng").eq("type","paomadeng").last("limit 1"));
        map.put("contents",contents);
        map.put("paomadeng",paomadeng.getValue());
        map.put("appAdmin",appAdmin);
        return new ResponseBean(200,1,"请求成功！",map);
    }
    /**
     * 修改app用户语言
     * @param yuyan  语言
     * @param token  用户请求令牌
     * @return
     */
    @RequestMapping("updateAppadminYuyan")
    public ResponseBean updateAppadmin(String yuyan,@RequestHeader(value = "token" , required = false) String token){

        if(StringUtil.isNull(yuyan)) {
            return ResponseBean.error("设置的语言不能为空") ;
        }
        String uid = JwtUtil.getUsername(token);
        AppAdmin appAdmin = adminService.getById(uid);
        if (appAdmin == null){
            return ResponseBean.error("请先登录！") ;
        }
        if(appAdmin.getStatus() == 0) {
            return new ResponseBean(1,1,"用户已禁用","");
        }
        appAdmin.setYuyan(yuyan);
        if(adminService.updateById(appAdmin)){
            return  ResponseBean.OK;
        }else {
            return  ResponseBean.error("操作失败！");
        }
    }

    /**
     * 手动断开主机连接
     * @param id  主机id
     * @param shebei_id 设备ID
     * @param token  用户请求令牌
     * @return
     */
    @RequestMapping("duankai_lianjie")
    public ResponseBean duankai_lianjie(@RequestParam(value = "id",required = false) String id,String shebei_id,@RequestHeader(value = "token" , required = false) String token) throws InterruptedException {

        String uid = JwtUtil.getUsername(token);
        AppAdmin appAdmin = adminService.getById(uid);
        if (appAdmin == null) {
            return ResponseBean.error("请先登录！");
        }
        if(stringRedisTemplate.opsForHash().hasKey("time_" + shebei_id,"type")){
            Zhuji zhuji = zhujiService.getById(id);
            if (zhuji == null) {
                return ResponseBean.error("找不到该主机！");
            }
            if (zhuji.getSy_lianjie_num() - 1 >= 0) {
                zhuji.setSy_lianjie_num(zhuji.getSy_lianjie_num() - 1);
            }
            if (zhujiService.updateById(zhuji)) {
                QueryWrapper<Zhuji> queryWrapper = new QueryWrapper();
                queryWrapper.select("sum(lianjie_num) as lianjie_num,sum(sy_lianjie_num) as sy_lianjie_num");
                queryWrapper.eq("area_id", zhuji.getArea_id());
                Zhuji zj = zhujiService.getOne(queryWrapper);
                if (zj != null && zj.getLianjie_num() > zj.getSy_lianjie_num()) {  //设置地区状态为绿色  未满
                    Area area = areaService.getById(zhuji.getArea_id());
                    area.setStatus(0);
                    areaService.updateById(area);
                }
                stringRedisTemplate.delete("time_" + shebei_id);
                return ResponseBean.OK;
            } else {
                return ResponseBean.error("操作失败！");
            }
        }
        return ResponseBean.OK;
    }
}
